﻿// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// Website: https://www.blazor.zone or https://argozhang.github.io/

using BootstrapBlazor.Components;
using BootstrapBlazor.Shared.Common;
using BootstrapBlazor.Shared.Components;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Rendering;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.Extensions.Localization;

namespace BootstrapBlazor.Shared.Samples;

/// <summary>
/// 
/// </summary>
public sealed partial class Trees
{
    [NotNull]
    private BlockLogger? Trace { get; set; }

    [NotNull]
    private BlockLogger? TraceChecked { get; set; }

    [NotNull]
    private BlockLogger? TraceCheckedItems { get; set; }

    [Inject]
    [NotNull]
    private IStringLocalizer<Foo>? Localizer { get; set; }

    private Foo Model => Foo.Generate(Localizer);

    private List<TreeItem> Items { get; set; } = TreeDataFoo.GetTreeItems();

    private List<TreeItem> CheckedItems { get; set; } = GetCheckedItems();

    private List<TreeItem> ExpandItems { get; set; } = GetExpandItems();

    private List<TreeItem>? AsyncItems { get; set; }

    /// <summary>
    /// OnInitializedAsync 方法
    /// </summary>
    /// <returns></returns>
    protected override async Task OnInitializedAsync()
    {
        await OnLoadAsyncItems();
    }

    private async Task OnLoadAsyncItems()
    {
        AsyncItems = null;
        await Task.Delay(2000);
        AsyncItems = TreeDataFoo.GetTreeItems();
    }

    private static List<TreeItem> GetCheckedItems()
    {
        var ret = TreeDataFoo.GetTreeItems();
        ret[1].Items[1].Checked = true;
        return ret;
    }

    private static List<TreeItem> GetExpandItems()
    {
        var ret = TreeDataFoo.GetTreeItems();
        ret[1].IsCollapsed = false;
        return ret;
    }

    private List<TreeItem> DisabledItems { get; set; } = GetDisabledItems();

    private static List<TreeItem> GetDisabledItems()
    {
        var ret = TreeDataFoo.GetTreeItems();
        ret[1].Items[1].IsDisabled = true;
        return ret;
    }

    private static List<TreeItem> GetIconItems() => TreeDataFoo.GetTreeItems();

    private static List<TreeItem> GetLazyItems()
    {
        var ret = TreeDataFoo.GetTreeItems();
        ret[1].Items[0].IsCollapsed = false;
        ret[1].Items[1].Text = "懒加载";
        ret[1].Items[1].HasChildNode = true;
        ret[1].Items[2].Text = "懒加载延时";
        ret[1].Items[2].HasChildNode = true;
        ret[1].Items[2].Key = "Delay";

        return ret;
    }

    private static List<TreeItem> GetTemplateItems()
    {
        var ret = TreeDataFoo.GetTreeItems();
        ret[0].Template = BootstrapDynamicComponent.CreateComponent<CustomerTreeItem>().Render();
        return ret;
    }

    private static List<TreeItem> GetColorItems()
    {
        var ret = TreeDataFoo.GetTreeItems();
        ret[0].CssClass = "text-primary";
        ret[1].CssClass = "text-success";
        ret[2].CssClass = "text-danger";
        return ret;
    }

    private class CustomerTreeItem : ComponentBase
    {
        [Inject]
        [NotNull]
        private ToastService? ToastService { get; set; }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="builder"></param>
        protected override void BuildRenderTree(RenderTreeBuilder builder)
        {
            builder.OpenComponent<Button>(0);
            builder.AddAttribute(1, nameof(Button.Icon), "fa fa-fa");
            builder.AddAttribute(2, nameof(Button.Text), "Click");
            builder.AddAttribute(3, nameof(Button.OnClick), EventCallback.Factory.Create<MouseEventArgs>(this, e =>
            {
                ToastService.Warning("自定义 TreeItem", "测试 TreeItem 按钮点击事件");
            }));
            builder.CloseComponent();
        }
    }

    private Task OnTreeItemClick(TreeItem item)
    {
        Trace.Log($"TreeItem: {item.Text} clicked");
        return Task.CompletedTask;
    }

    private Task OnTreeItemChecked(TreeItem item)
    {
        var state = item.Checked ? "选中" : "未选中";
        TraceChecked.Log($"TreeItem: {item.Text} {state}");
        return Task.CompletedTask;
    }

    private static async Task OnExpandNode(TreeItem item)
    {
        if (!item.Items.Any() && item.HasChildNode && !item.ShowLoading)
        {
            item.ShowLoading = true;
            if (item.Key?.ToString() == "Delay")
            {
                await Task.Delay(800);
            }
            item.Items.AddRange(new TreeItem[]
            {
                    new TreeItem()
                    {
                        Text = "懒加载子节点1",
                        HasChildNode = true
                    },
                    new TreeItem() { Text = "懒加载子节点2" }
            });
            item.ShowLoading = false;
        }
    }

    private Task OnTreeItemChecked(List<TreeItem> items)
    {
        TraceCheckedItems.Log($"当前共选中{items.Count}项");
        return Task.CompletedTask;
    }

    /// <summary>
    /// 获得属性方法
    /// </summary>
    /// <returns></returns>
    private static IEnumerable<AttributeItem> GetAttributes() => new AttributeItem[]
    {
        // TODO: 移动到数据库中
        new AttributeItem() {
            Name = "Items",
            Description = "菜单数据集合",
            Type = "IEnumerable<TreeItem>",
            ValueList = " — ",
            DefaultValue = "new List<TreeItem>(20)"
        },
        new AttributeItem() {
            Name = "ClickToggleNode",
            Description = "是否点击节点时展开或者收缩子项",
            Type = "bool",
            ValueList = "true|false",
            DefaultValue = "false"
        },
        new AttributeItem() {
            Name = "ShowCheckbox",
            Description = "是否显示 CheckBox",
            Type = "bool",
            ValueList = "true|false",
            DefaultValue = "false"
        },
        new AttributeItem() {
            Name = "ShowIcon",
            Description = "是否显示 Icon",
            Type = "bool",
            ValueList = "true|false",
            DefaultValue = "false"
        },
        new AttributeItem() {
            Name = "ShowSkeleton",
            Description = "是否显示加载骨架屏",
            Type = "bool",
            ValueList = "true|false",
            DefaultValue = "false"
        },
        new AttributeItem() {
            Name = "OnTreeItemClick",
            Description = "树形控件节点点击时回调委托",
            Type = "Func<TreeItem, Task>",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = "OnTreeItemChecked",
            Description = "树形控件节点选中时回调委托",
            Type = "Func<TreeItem, Task>",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = "OnExpandNode",
            Description = "树形控件节点展开回调委托",
            Type = "Func<TreeItem, Task>",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = "OnCheckedItems",
            Description = "树形控件获取所有选中节点回调委托",
            Type = "Func<List<TreeItem>, Task>",
            ValueList = " — ",
            DefaultValue = " — "
        }
    };

    private static IEnumerable<AttributeItem> GetTreeItemAttributes() => new AttributeItem[]
    {
        // TODO: 移动到数据库中
        new AttributeItem() {
            Name = nameof(TreeItem.Key),
            Description = "TreeItem 标识",
            Type = "object?",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = "Items",
            Description = "子节点数据源",
            Type = "IEnumerable<TreeItem>",
            ValueList = " — ",
            DefaultValue = "new List<TreeItem>(20)"
        },
        new AttributeItem() {
            Name = "Text",
            Description = "显示文字",
            Type = "string",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = "Icon",
            Description = "显示图标",
            Type = "string",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = "CssClass",
            Description = "节点自定义样式",
            Type = "string",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = "Checked",
            Description = "是否被选中",
            Type = "bool",
            ValueList = "true|false",
            DefaultValue = "false"
        },
        new AttributeItem() {
            Name = nameof(TreeItem.IsDisabled),
            Description = "是否被禁用",
            Type = "bool",
            ValueList = "true|false",
            DefaultValue = "false"
        },
        new AttributeItem() {
            Name = "IsCollapsed",
            Description = "是否展开",
            Type = "bool",
            ValueList = "true|false",
            DefaultValue = "true"
        },
        new AttributeItem() {
            Name = nameof(TreeItem.Tag),
            Description = "TreeItem 附加数据",
            Type = "object?",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = nameof(TreeItem.HasChildNode),
            Description = "是否有子节点",
            Type = "bool",
            ValueList = " true|false ",
            DefaultValue = " false "
        },
        new AttributeItem() {
            Name = nameof(TreeItem.ShowLoading),
            Description = "是否显示子节点加载动画",
            Type = "bool",
            ValueList = " true|false ",
            DefaultValue = " false "
        },
        new AttributeItem()
        {
            Name = nameof(TreeItem.Template),
            Description = "子节点模板",
            Type = nameof(RenderFragment),
            ValueList = " — ",
            DefaultValue = " — "
        }
    };
}
